<?php

use Mapper\MemberModel as MemberMapper;
use Mapper\GamecircleModel as GameCircleMapper;
use Mapper\GamecirclememberModel as GameCircleMemberMapper;
use Mapper\GamecirclelogModel as GameCircleLogMapper;
use Mapper\FriendModel as FriendMapper;

class GamecircleController extends \Base\ApiController {

    /**
     * @desc 电竞圈创建
     * @return false
     */
    public function addAction() {
        $request     = $this->getRequest();
        $uid         = \Lib\User::getInstance()->id();
        $name        = (string)$request->get('name');
        $address     = (string)$request->get('address');
        $circleNum   = (string)$request->get('circle_num');
        $mainGame    = (string)$request->get('main_game');
        $longitude   = (float)$request->get('longitude');
        $latitude    = (float)$request->get('latitude');
        $totalNumber = (int)$request->get('total_number');
        $level       = (int)$request->get('level');
        $manifesto   = (string)$request->get('manifesto');
        $imgUrl      = (string)$request->get('img_url');

        if(empty($name)) {
            return \Response::error('电竞圈名称不能为空', 10402);
        }

        if(empty($circleNum)) {
            return \Response::error('环信的群id不能为空', 10416);
        }

        if(empty($address)) {
            return \Response::error('电竞圈地址不能为空', 10418);
        }

        if(empty($mainGame)) {
            return \Response::error('主打游戏不能为空', 10403);
        }

        if(empty($totalNumber)) {
            return \Response::error('电竞圈人数不能为空', 10404);
        }

        if(empty($level)) {
            return \Response::error('电竞圈等级不能为空', 10405);
        }

        if(($longitude > 180 || $longitude < 0 || $latitude > 90 || $latitude < 0)) {
            return \Response::error('经纬度数据有误, 请重新获取', 10413);
        }

        $memberMapper = MemberMapper::getInstance();
        $memberModel  = $memberMapper->findById($uid);

        if(!$memberModel instanceof \MemberModel) {
            return \Response::error('无效的用户id', 10110);
        }

        $model  = new \GameCircleModel();
        $mapper = GameCircleMapper::getInstance();

        $model->setMember_id($uid);
        $model->setName($name);
        $model->setAddress($address);
        $model->setLetter(\Lib\Pinyin::to_first($name));
        $model->setCircle_num($circleNum);
        $model->setMain_game($mainGame);
        $model->setLongitude($longitude * \Lib\Consts::LATITUDE_LONGITUDE_CONVERSION);
        $model->setLatitude($latitude * \Lib\Consts::LATITUDE_LONGITUDE_CONVERSION);
        $model->setNumber($totalNumber);
        $model->setLevel($level);
        $model->setManifesto($manifesto);
        $model->setImg_url($imgUrl);
        $model->setAdd_time(time());
        $model->setStatus(\Lib\Consts::GAME_CIRCLE_NORMAL);

        $mapper->begin();

        $circleId = $mapper->insert($model);

        if($circleId <= 0) {
            $mapper->rollback();
            return \Response::error('创建电竞圈失败, 请重试', 10414);
        }

        $circleMemberModel = new \GameCircleMemberModel();
        $gameCircleMapper  = GameCircleMemberMapper::getInstance();
        $circleMemberModel->setMember_id($uid);
        $circleMemberModel->setGame_circle_id($circleId);
        $circleMemberModel->setType(\Lib\Consts::GAME_CIRCLE_MEMBER_MASTER);
        $circleMemberModel->setAdd_time(time());
        $circleMemberModel->setMsg_setting(\Lib\Consts::GAME_INFORM_RECEIVER_BY_AUTO);

        if(!$gameCircleMapper->insert($circleMemberModel)) {
            $mapper->rollback();
            return \Response::error('添加电竞圈群主信息失败, 请重试', 10407);
        }

        $logModel  = new \GameCircleLogModel();
        $logMapper = GameCircleLogMapper::getInstance();
        $logModel->setMember_id($uid);
        $logModel->setStatus(\Lib\Consts::GAME_CIRCLE_LOG_CREATE);
        $logModel->setAdd_time(time());

        if(!$logMapper->insert($logModel)) {
            $mapper->rollback();
            return \Response::error('添加电竞圈记录失败', 10410);
        }

        $mapper->commit();

        return \Response::data('创建电竞圈成功', 10408);
    }

    /**
     * 电竞圈详情信息
     * @return false
     */
    public function detailAction() {
        $request  = $this->getRequest();
        $circleId = (int)$request->get('circle_id');
        $ownUid   = \Lib\User::getInstance()->id();

        $mapper = GameCircleMapper::getInstance();
        $model  = $mapper->fetch(['id' => $circleId, 'status' => \Lib\Consts::GAME_CIRCLE_NORMAL]);

        if(!$model instanceof \GameCircleModel) {
            return \Response::error('电竞圈信息id有误', 10415);
        }

        $uid = $model->getMember_id();

        if(empty($uid)) {
            return \Response::error('Invalid Uid', 10110);
        }

        $memberMapper = memberMapper::getInstance();
        $memberModel  = $memberMapper->findById($uid);

        if(!$memberModel instanceof \MemberModel) {
            return \Response::error('Invalid Uid', 10110);
        }

        $data             = $model->toArray();
        $data['nickname'] = $memberModel->getNick_name();

        // type  我创建的1, 我加入的2, 未加入的3
        if($uid === $ownUid) {
            $data['type'] = '1';
        } else {
            $circleMemberMapper = GameCircleMemberMapper::getInstance();
            $circleMemberModel  = $circleMemberMapper->fetch(['member_id' => $ownUid, 'game_circle_id' => $circleId]);
            $data['type']       = ($circleMemberModel instanceof \GameCircleMemberModel) ? '2' : '3';
        }

        return \Response::data($data);
    }

    /**
     * @desc 加入电竞圈
     * @return false
     */
    public function joinAction() {
        $request  = $this->getRequest();
        $uid      = \Lib\User::getInstance()->id();
        $circleId = (int)$request->get('circle_id');

        $gameCircleMapper = GameCircleMemberMapper::getInstance();
        $model            = $gameCircleMapper->fetch(['member_id' => $uid, 'id' => $circleId]);

        if($model instanceof \GameCircleMemberModel) {
            return \Response::error('用户已存在, 不能重复加入', 10412);
        }

        $circleMemberModel = new \GameCircleMemberModel();
        $circleMemberModel->setMember_id($uid);
        $circleMemberModel->setGame_circle_id($circleId);
        $circleMemberModel->setType(\Lib\Consts::GAME_CIRCLE_MEMBER_ORDINARY);
        $circleMemberModel->setAdd_time(time());
        $circleMemberModel->setMsg_setting(\Lib\Consts::GAME_INFORM_RECEIVER_BY_AUTO);

        $gameCircleMapper->begin();

        if(!$gameCircleMapper->insert($circleMemberModel)) {
            $gameCircleMapper->rollback();
            return \Response::error('添加电竞圈群主信息失败, 请重试', 10407);
        }

        $logModel  = new \GameCircleLogModel();
        $logMapper = GameCircleLogMapper::getInstance();
        $logModel->setMember_id($uid);
        $logModel->setStatus(\Lib\Consts::GAME_CIRCLE_LOG_CREATE);
        $logModel->setAdd_time(time());

        if(!$logMapper->insert($logModel)) {
            $gameCircleMapper->rollback();
            return \Response::error('添加电竞圈记录失败', 10410);
        }

        $gameCircleMapper->commit();

        return \Response::data(null);
    }

    /**
     * @desc 退出电竞圈(真)
     * @return false
     */
    public function quitAction() {
        $request  = $this->getRequest();
        $uid      = \Lib\User::getInstance()->id();
        $circleId = (int)$request->get('circle_id');

        $gameCircleMapper = GameCircleMemberMapper::getInstance();

        $gameCircleMapper->begin();

        if(!$gameCircleMapper->del(['member_id' => $uid, 'game_circle_id' => $circleId])) {
            $gameCircleMapper->rollback();
            return \Response::error('退出电竞圈失败, 请重试', 10407);
        }

        $logModel  = new \GameCircleLogModel();
        $logMapper = GameCircleLogMapper::getInstance();
        $logModel->setMember_id($uid);
        $logModel->setStatus(\Lib\Consts::GAME_CIRCLE_LOG_QUIT);
        $logModel->setAdd_time(time());

        if(!$logMapper->insert($logModel)) {
            $gameCircleMapper->rollback();
            return \Response::error('添加电竞圈记录失败', 10410);
        }

        $gameCircleMapper->commit();

        return \Response::data(null);
    }

    /**
     * @desc 我的电竞圈(包括自己创建的)
     *
     * @return false
     */
    public function mycircleAction() {
        $uid    = \Lib\User::getInstance()->id();
        $mapper = GameCircleMemberMapper::getInstance();
        $models = $mapper->fetchAll(['member_id' => $uid], 'add_time DESC');

        if(empty($models)) {
            return \Response::data([], '我的电竞圈信息为空');
        }

        $return           = [];
        $gameCircleMapper = GameCircleMapper::getInstance();

        foreach($models as $model) {
            $myCircleDetailModel = $gameCircleMapper->findById($model->getGame_circle_id());

            if(!$myCircleDetailModel instanceof \GameCircleModel) {
                return \Response::error('无效的电竞圈id', 10419);
            }

            $data               = $model->toArray();
            $data['name']       = $myCircleDetailModel->getName();
            $letter             = $myCircleDetailModel->getLetter();
            $data['letter']     = $letter;
            $data['main_game']  = $myCircleDetailModel->getMain_game();
            $data['img_url']    = $myCircleDetailModel->getImg_url();
            $data['circle_num'] = $myCircleDetailModel->getCircle_num();
            $return[$letter][]  = $data;
        }

        return \Response::data($return);
    }

    /**
     * @desc 删除电竞圈(伪)
     *
     * @return false
     */
    public function delAction() {
        $request  = $this->getRequest();
        $uid      = \Lib\User::getInstance()->id();
        $circleId = (int)$request->get('circle_id');

        $circleMapper = GameCircleMapper::getInstance();
        $model        = $circleMapper->fetch(['member_id' => $uid, 'id' => $circleId]);

        if(!$model instanceof \GameCircleModel) {
            return \Response::error('对应的电竞圈不存在', 10409);
        }

        $model->setStatus(\Lib\Consts::GAME_CIRCLE_DELETE);
        $model->setUpdate_time(time());

        $circleMapper->begin();

        if(!$circleMapper->update($model, ['member_id' => $uid, 'id' => $circleId])) {
            $circleMapper->rollback();
            return \Response::error('删除电竞圈失败, 请重试', 10411);
        }

        $logModel  = new \GameCircleLogModel();
        $logMapper = GameCircleLogMapper::getInstance();
        $logModel->setMember_id($uid);
        $logModel->setStatus(\Lib\Consts::GAME_CIRCLE_LOG_DELETE);
        $logModel->setAdd_time(time());

        if(!$logMapper->insert($logModel)) {
            $circleMapper->rollback();
            return \Response::error('添加电竞圈记录失败', 10410);
        }

        $circleMapper->commit();
        return \Response::data(null);
    }

    /**
     * @desc 身边的电竞圈
     * @return false
     */
    public function nearbylistAction() {
        $uid         = \Lib\User::getInstance()->id();
        $request     = $this->getRequest();
        $page        = (int)$request->get('page', 1);
        $perPage     = (int)$request->get('per_page', 10);
        $page        = max(1, $page);
        $perPage     = min(30, $perPage);
        $limit       = $perPage;
        $offset      = $limit * ($page - 1);
        $return      = [];
        $distanceArr = [];

        $memberMapper = MemberMapper::getInstance();
        $memberModel  = $memberMapper->findById($uid);

        if(!$memberModel instanceof \MemberModel) {
            return \Response::error('用户信息有误, 请联系客服', 10417);
        }

        $longitude = $memberModel->getLongitude();
        $latitude  = $memberModel->getlatitude();

        if($longitude < 0 || $latitude < 0 || $longitude > 180 || $latitude > 90) {
            return \Response::error('经纬度数据有误, 请重新获取', 10118);
        }

        $gameCircleMapper = GameCircleMapper::getInstance();

        $llValue    = \Lib\Consts::LATITUDE_LONGITUDE_1KM;
        $conversion = \Lib\Consts::LATITUDE_LONGITUDE_CONVERSION;

        $models = $gameCircleMapper->fetchAll([
            'status'         => \Lib\Consts::GAME_CIRCLE_NORMAL,
            'longitude <= ?' => $longitude * $conversion + $llValue,
            'longitude >= ?' => $longitude * $conversion - $llValue,
            'latitude <= ?'  => $latitude * $conversion + $llValue,
            'latitude >= ?'  => $latitude * $conversion - $llValue,
        ], 'id', $limit, $offset);

        foreach($models as $model) {
            $arr             = $model->toArray();
            $longitudeTo     = $model->getLongitude() / $conversion;
            $latitudeTo      = $model->getLatitude() / $conversion;
            $distance        = $this->getDistance($longitude, $latitude, $longitudeTo, $latitudeTo);
            $arr['distance'] = $distance;
            $distanceArr[]   = $distance;
            $return[]        = $arr;
        }

        array_multisort($distanceArr, SORT_ASC, $return);

        return \Response::data($return, '获取附近的人');
    }

    /**
     * @desc 根据两点间的经纬度计算距离
     * @param $lng1 float 经度值
     * @param $lat1 float 纬度值
     * @param $lng2 float
     * @param $lat2 float
     * @return float
     */
    public function getDistance($lng1, $lat1, $lng2, $lat2) {
        $earthRadius = \Lib\Consts::EARTH_RADIUS;
        $lat1        = ($lat1 * pi()) / 180;
        $lng1        = ($lng1 * pi()) / 180;
        $lat2        = ($lat2 * pi()) / 180;
        $lng2        = ($lng2 * pi()) / 180;

        $calcLongitude      = $lng2 - $lng1;
        $calcLatitude       = $lat2 - $lat1;
        $stepOne            = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
        $stepTwo            = 2 * asin(min(1, sqrt($stepOne)));
        $calculatedDistance = $earthRadius * $stepTwo;

        return round($calculatedDistance);
    }

    /**
     * @desc 邀请好友加入电竞圈列表 1.好友列表 2.提取好友的详细信息 3.添加标志字段
     *
     * @return false
     */
    public function invitelistAction() {
        $uid          = \Lib\User::getInstance()->id();
        $request      = $this->getRequest();
        $gameCircleId = (int)$request->get('game_circle_id');

        if($gameCircleId <= 0) {
            return Response::error('电竞圈的id不能为空', 20208);
        }

        $friendMapper  = FriendMapper::getInstance();
        $friendModels  = $friendMapper->fetchAll(['member_id' => $uid]);
        $friendListIds = [];

        if(empty($friendListIds)) {
            return Response::error('还没有添加好友', 20209);
        }

        foreach($friendModels as $friendData) {
            $friendListIds[] = $friendData->getFriend_id();
        }

        $memberMapper           = MemberMapper::getInstance();
        $friendDetailModels     = $memberMapper->fetchAll(['id' => $friendListIds], 'letter');
        $gameCircleMemberMapper = GameCircleMemberMapper::getInstance();
        $data                   = [];

        foreach($friendDetailModels as $friendDetailModel) {
            $statusModel = $gameCircleMemberMapper->fetch([
                'member_id'      => $friendDetailModel->getId(),
                'game_circle_id' => $gameCircleId,
            ]);

            $friendDetailData               = $friendDetailModel->toArray();
            $friendDetailData['isInCircle'] = empty($statusModel) ? 0 : 1;
            $data[]                         = $friendDetailData;
        }

        return Response::data($data);
    }

    /**
     * @desc 群成员列表
     *
     * @return false
     */
    public function memberlistAction() {
        $request  = $this->getRequest();
        $circleId = (int)$request->get('circle_id');
        $search   = (string)$request->get('search');
        $uid      = \Lib\User::getInstance()->id();
        $return   = [];
        $uids     = [];

        $memberMapper = MemberMapper::getInstance();
        $ownModel     = $memberMapper->findById($uid);

        if(!$ownModel instanceof \MemberModel) {
            return \Response::error('用户信息有误, 请联系客服', 10417);
        }

        $circleMemberMapper = GameCircleMemberMapper::getInstance();
        $circleMemberModels = $circleMemberMapper->fetchAll(['game_circle_id' => $circleId]);

        if(empty($circleMemberModels)) {
            return \Response::data([]);
        }

        foreach($circleMemberModels as $circleMemberModel) {
            $uids[] = $circleMemberModel->getMember_id();
        }

        $where = ['id' => $uids];

        if (!empty($search)) {
            $where = array_merge($where, ["`nick_name` like '%" . $search . "%'"]);
        }

        $memberModels = $memberMapper->fetchAll($where);

        if(empty($memberModels)) {
            return \Response::data([]);
        }

        $conversion = \Lib\Consts::LATITUDE_LONGITUDE_CONVERSION;
        $latitude   = $ownModel->getLatitude();
        $longitude  = $ownModel->getLongitude();

        foreach($memberModels as $memberModel) {
            $data             = $memberModel->toArray();
            $longitudeTo      = $memberModel->getLongitude() / $conversion;
            $latitudeTo       = $memberModel->getLatitude() / $conversion;
            $distance         = $this->getDistanceAction($longitude, $latitude, $longitudeTo, $latitudeTo);
            $data['distance'] = $distance;
            $return[]         = $data;
        }

        return \Response::data($return, '获取附近的人');
    }

    /**
     * @des 电竞圈搜索
     * @var (int)$type (1-id 2-name)
     * @var (string)$keyWord
     *
     * @return false
     */
    public function searchAction() {
        $uid    = \Lib\User::getInstance()->id();
        $request = $this->getRequest();
        $type    = (int)$request->get('type');
        $keyWord = (string)$request->get('key_word');
        $page    = (int)$request->get('page', 1);
        $prePage = (int)$request->get('pre_page', 15);
        $page    = max(1, $page);
        $prePage = min(30, $prePage);
        $limit   = $prePage;
        $offset  = $limit * ($page - 1);

        if( empty($type) ) {
            return \Response::error('类型不能为空',20200);
        }

        if( $keyWord =='' ) {
            return \Response::error('内容不能为空',20200);
        }

        $gameCircleMapper = GameCircleMapper::getInstance();

        switch ($type) {
            case 1:
                $where = " name like '%".$keyWord."%' ";
                break;
            case 2:
                $where = " id like '%".$keyWord."%' ";
                break;

            default:return \Response::error('类型错误',20200);
        }

        $data = $gameCircleMapper->fetchAll($where,'',$limit,$offset);

        return \Response::data($data,'搜索结果');
    }
}
